﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using SlimDX;

namespace System.Windows.Media.Media3D10
{
    /// <summary>
    /// Fourni des méthodes pour générer des cubes par tesselation
    /// </summary>
    public static class CubeTesselator
    {
        /// <summary>
        /// Génère un cube par tesselation.
        /// </summary>
        /// <param name="sideLength">Longueur d'arête du cube souhaité.</param>
        /// <returns><see cref="MeshGeometry3D10"/> représentant le cube.</returns>
        public static MeshGeometry3D10 Tessellate(float sideLength)
        {
            float a = sideLength / 2;

            MeshGeometry3D10 returnValue = new MeshGeometry3D10();

            returnValue.Positions.Add(new Vector3(-a, a, -a));
            returnValue.Positions.Add(new Vector3(a, a, -a));
            returnValue.Positions.Add(new Vector3(a, a, a));
            returnValue.Positions.Add(new Vector3(-a, a, a)); 

            returnValue.Positions.Add(new Vector3(-a, -a, -a)); 
            returnValue.Positions.Add(new Vector3(a, -a, -a)); 
            returnValue.Positions.Add(new Vector3(a, -a, a)); 
            returnValue.Positions.Add(new Vector3(-a, -a, a)); 

            returnValue.Positions.Add(new Vector3(-a, -a, a));
            returnValue.Positions.Add(new Vector3(-a, -a, -a));
            returnValue.Positions.Add(new Vector3(-a, a, -a)); 
            returnValue.Positions.Add(new Vector3(-a, a, a)); 

            returnValue.Positions.Add(new Vector3(a, -a, a)); 
            returnValue.Positions.Add(new Vector3(a, -a, -a)); 
            returnValue.Positions.Add(new Vector3(a, a, -a)); 
            returnValue.Positions.Add(new Vector3(a, a, a)); 

            returnValue.Positions.Add(new Vector3(-a, -a, -a)); 
            returnValue.Positions.Add(new Vector3(a, -a, -a));
            returnValue.Positions.Add(new Vector3(a, a, -a)); 
            returnValue.Positions.Add(new Vector3(-a, a, -a));

            returnValue.Positions.Add(new Vector3(-a, -a, a));
            returnValue.Positions.Add(new Vector3(a, -a, a));
            returnValue.Positions.Add(new Vector3(a, a, a));
            returnValue.Positions.Add(new Vector3(-a, a, a));

            foreach (var pos in returnValue.Positions)
            {
                returnValue.Normals.Add(Vector3.Normalize(pos));
            }

            returnValue.TriangleIndices.Add(3);
            returnValue.TriangleIndices.Add(1);
            returnValue.TriangleIndices.Add(0);
            
            returnValue.TriangleIndices.Add(2);
            returnValue.TriangleIndices.Add(1);
            returnValue.TriangleIndices.Add(3);
            
            returnValue.TriangleIndices.Add(6);
            returnValue.TriangleIndices.Add(4);
            returnValue.TriangleIndices.Add(5);
            
            returnValue.TriangleIndices.Add(7);
            returnValue.TriangleIndices.Add(4);
            returnValue.TriangleIndices.Add(6);
            
            returnValue.TriangleIndices.Add(11);
            returnValue.TriangleIndices.Add(9);
            returnValue.TriangleIndices.Add(8);
            
            returnValue.TriangleIndices.Add(10);
            returnValue.TriangleIndices.Add(9);
            returnValue.TriangleIndices.Add(11);
            
            returnValue.TriangleIndices.Add(14);
            returnValue.TriangleIndices.Add(12);
            returnValue.TriangleIndices.Add(13);
            
            returnValue.TriangleIndices.Add(15);
            returnValue.TriangleIndices.Add(12);
            returnValue.TriangleIndices.Add(14);
            
            returnValue.TriangleIndices.Add(19);
            returnValue.TriangleIndices.Add(17);
            returnValue.TriangleIndices.Add(16);
            
            returnValue.TriangleIndices.Add(18);
            returnValue.TriangleIndices.Add(17);
            returnValue.TriangleIndices.Add(19);
            
            returnValue.TriangleIndices.Add(22);
            returnValue.TriangleIndices.Add(20);
            returnValue.TriangleIndices.Add(21);
            
            returnValue.TriangleIndices.Add(23);
            returnValue.TriangleIndices.Add(20);
            returnValue.TriangleIndices.Add(22);

            return returnValue;
        }
    }
}
